/*
 * Copyright (c) Huawei Device Co., Ltd. 2023. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "reader.h"

#include "isecure_element_reader.h"
#include "loghelper.h"
#include "se_service.h"
#include "session.h"

namespace OHOS {
namespace SE {
namespace OMAPI {

Reader::Reader(std::weak_ptr<SEService> service, const std::string& readName, sptr<ISecureElementReader> readerIface)
    : readerName_(readName), boundService_(service), readerIface_(readerIface)
{
}

Reader::~Reader() {}

int Reader::InnerCheckReaderStatus(void)
{
    // don't lock for mutex_ here, already locked outter.
    if (boundService_.expired() || !readerIface_) {
        ErrorLog("InnerCheckReaderStatus boundService_ or readerIface_ is null!");
        return ErrorCode::SE_ILLEGAL_STATE_ERROR;
    }
    return ErrorCode::SE_SUCCESS;
}

int Reader::GetName(std::string& readerName)
{
    std::lock_guard<std::mutex> lock(mutex_);
    readerName = readerName_;
    return ErrorCode::SE_SUCCESS;
}

int Reader::OpenSession(std::shared_ptr<Session>& session)
{
    std::lock_guard<std::mutex> lock(mutex_);
    session = std::shared_ptr<Session>();
    int ret = InnerCheckReaderStatus();
    if (ret != ErrorCode::SE_SUCCESS) {
        ErrorLog("OpenSession failed status, res = %{public}d", ret);
        return ret;
    }

    sptr<ISecureElementSession> sessionIface;
    ret = readerIface_->OpenSession(sessionIface);
    if (sessionIface != nullptr) {
        session = std::make_shared<Session>(boundService_, sessionIface, shared_from_this());
    } else {
        ErrorLog("OpenSession failed ipc, res = %{public}d", ret);
    }
    return ret;
}

int Reader::IsSecureElementPresent(bool &isPresent)
{
    std::lock_guard<std::mutex> lock(mutex_);
    isPresent = false;
    int ret = InnerCheckReaderStatus();
    if (ret != ErrorCode::SE_SUCCESS) {
        ErrorLog("IsSecureElementPresent failed, res = %{public}d", ret);
        return ret;
    }

    return readerIface_->IsSecureElementPresent(isPresent);
}

int Reader::GetSEService(std::weak_ptr<SEService>& service)
{
    std::lock_guard<std::mutex> lock(mutex_);
    service = boundService_;
    return ErrorCode::SE_SUCCESS;
}

int Reader::CloseSessions(void)
{
    std::lock_guard<std::mutex> lock(mutex_);
    int ret = InnerCheckReaderStatus();
    if (ret != ErrorCode::SE_SUCCESS) {
        ErrorLog("CloseSessions failed, res = %{public}d", ret);
        return ret;
    }

    return readerIface_->CloseSessions();
}

int Reader::Reset(bool &resetStatus)
{
    std::lock_guard<std::mutex> lock(mutex_);
    resetStatus = false;
    int ret = InnerCheckReaderStatus();
    if (ret != ErrorCode::SE_SUCCESS) {
        ErrorLog("Reset failed, res = %{public}d", ret);
        return ret;
    }

    return readerIface_->Reset(resetStatus);
}
}  // namespace OMAPI
}  // namespace SE
}  // namespace OHOS